New Developments in the Notebook Environment

John Fultz

Wolfram Research, Inc.

Some great things we've done in the Notebook Front End recently...

({{Interactive Graphics}, {User Interface Controls}, {The Debugger}})

Some great things we've done in the Front End recently...
that I'm not talking about.

({{Interactive Graphics, Chris Carlson, 1:00}, {User Interface Controls, Theo Gray, 2:00}, {The Debugger, Tom Wickham-Jones, 4:00}})

Some great things we've done in the Front End recently...
that I'm not talking about.

({{Interactive Graphics, Chris Carlson, 1:00}, {User Interface Controls, Theo Gray, 2:00}, {The Debugger, Tom Wickham-Jones, 4:00}})

What I'm talking about: Everything else

Syntax Coloring

The Old

Plot[Sin[x], {x, 0, 2π]

Syntax Coloring

The Old

Plot[Sin[x], {x, 0, 2π]

The New

Plot[Sin[x], {x, 0, 2π]

Syntax Coloring

Other incomplete forms

Unmatched infix operators

2+

Unmatched string delimiters

"A string

Unmatched comment delimiters

(* a comment
f[x_]:=x!

Other syntactic hints

2+2
"A string"
(* A Comment *)

Syntax Coloring — What if I could color anything I wanted to?

Priority #1

min = Min[data];

The solution — Color any undefined variable

data = {5, 3, 9};
min = Min[data]

General::spell1 is dead and buried!

line=Line[{{0,0},{1,1}}]

log = Log[x]

Syntax Coloring Without the Syntax

Functions called with too many arguments

Log[Abs[base,z]]

NotebookOpen[ToFileName[{$TopDirectory, "Documentation", "English"}, "GettingStarted", "GettingStarted.nb"]]

DeleteFile["c:\\tmp\\2","c:\\tmp\\3"]

Functions called with bad options

Plot[x, {x, 0, 1}, PlotTitle->"A Linear Plot"]

ListDensityPlot[data,MeshRange->{{5,10},{5,10}}]

FullSimplify[((n!)/(n Gamma[n])),ExcudedForms->_!]

Syntax Coloring Without the Syntax

Local variables

Block[{$Path = Append[$Path, "C:\\Temp"]}, Get["MyFile.m"]]

Module[{x=x}, f[x]];

Special use variables

Table[dummy!, {dummy, 5, 10}]

Manipulate[Plot[((Abs[Sin[x]])^y), {x, 0, 1}], {y, 0, 4}]

Integrate[Sin[x]Cos[y], {x, 0,π}, y]

Solve[{(x-y) (z^2)==1,(x^2)==3,(y^2)+yy==3},{x,y,z}]

Pattern variables

Choose[setSize_, chooseSize_] := ((setSize!)/((setSize - chooseSize)!))

FoldList[#1+((#2)^2)&,0,Range[10]]

expr /.  x_+a_->x-a

Syntax Coloring — Our programming mistakes; what about yours?

Scoping conflicts

f[z_]:=Module[{x=z, y=(z^2), z=(z^3)}, x+y+z]

Assignment instead of equality check

If[x = y,Print["x is equal to y"]];

Shadowing

Global`xyz = 0;
System`xyz = 1;

xyz

Remove[System`xyz]

Advisory for new syntaxes

Plot[Sin[x], {x, 0, 2π}];

Syntax Coloring — Customize it!

Use the preferences dialog to change the syntax coloring defaults if you don't like them

f[z_]:=Module[{x=z, y=(z^2), z=(z^3)}, x+y+z]

If[x = y,Print["x is equal to y"]];

New user interface for X

A few of the things to expect...

New font system, which supports anti-aliasing and better Unicode support

Modern-looking interface, which can be changed at a whim

Much more powerful and less confusing standard tools like Open/Save, Print and Color Picker dialogs

Inherited Stylesheets

Demo...

The stylesheet is small

The stylesheet is portable across versions of Mathematica.

Most people don't create stylesheets from scratch...this is great for tweaking stylesheets

Ways in which you can extend a stylesheet

Add a style

Append or overwrite options to an existing style

Completely replace an existing style

Merge stylesheets

GridBox Improvements

Styles at the element level (i.e. not at the Row or Column levels)

Spanning rows and columns

Tables courtesy of The TEXbook by Donald Knuth

Better error-handling

dumbMistake=Range[10^6]

Upside down cell groups

ArrayPlot[CellularAutomaton[30,{{1},0},100,{All,All}],ColorRules->{0->White,1->Green},PlotLabel->Style["How was I generated?",FontSize->20]]

New palettes taking advantage of new user interface features

Help Browser Improvements

Programmatically tweaking output

The primitives...

Grid[{{0, 1}, {2, 3}}]

Row[{0, 1, 2, 3}]

Column[{0, 1, 2, 3}]

TextRow[{1,2,3,4}]

Graphics[{Line[{{0,0},{1,0.5}, {0, 1}, {1, 1.5}, {0, 2}}]},ImageSize->10]

And a way to span...

Grid[
{{1, 2, 3, 4, 5},
{2, "Spanning down", "Spanning right", , },
{3, , "Spanning both",  , },
{4, , , , },
{5, , , , }},RowLines->True, ColumnLines->True,GridFrame->True]

Programmatically tweaking output

An easy way to format information

CaptionedRulePlot[rule_]:=Column[{ArrayPlot[CellularAutomaton[rule,{{1},0},20],ImageSize->Tiny],Style["Rule "<>ToString[rule],"Section"]}]

CaptionedRulePlot[30]

Grid[Partition[Table[CaptionedRulePlot[i],{i,28,43}],{4}],RowAlignments->{Bottom}]

Programmatically constructing palettes

packagerow[str_]:= 
{Tooltip[Button["Load",Needs[str]], "Click to load " <> str],str}

FavoritePackages[]:=
Style[Grid[packagerow /@ $FavoritePackages,ColumnAlignments->Left,GridFrame->1],FontFamily->"Helvetica",TextAlignment->Center]

$FavoritePackages={
"Collaboration`",
"NumericalMath`EquationTrekker`",
"DiscreteMath`GraphPlot`",
"GUIKit`",
"WebServices`",
"DatabaseLink`"};

PalettePut[FavoritePackages[]];

$Packages

And then use the Install menu item to install it

New FE Import/Export technologies

No more Save As Special-style menus with lists of formats; they're all in the dialog box now

Many new formats supported.

EPS with TIFF previews
GIF
JPEG
PNG
TIFF
Rich Text Format on all platforms
SVG (export only)

Each format can have options dialogs specifying how to open/save it

And more formats coming because they're so easy to add

In fact, they're so easy to add, let's add one now

Let's build an importer
Part 1 — Write the code to do the import operation

Some toy code that reads in XLife/Life 1.05 files

ReadLifeFile[nb_,filename_,showDescriptions_] := Module[
{stringList = Import[filename, "Lines"],
descriptionList ,blockList,xmin,ymin,final},
descriptionList= Select[stringList, StringMatchQ[#,"#"~~{"C","D"}~~Whitespace ~~__]&];
descriptionList=StringReplace[descriptionList, "#"~~{"C","D"}~~Whitespace~~text___->text];
descriptionList=Style[#,FontFamily->"Times",ShowStringCharacters->False]&/@descriptionList;
stringList = Select[stringList,StringMatchQ[#,{"#P"~~Whitespace~~NumberString~~Whitespace~~NumberString~~___,
{".","*"}..}]&];
blockList = If[StringTake[stringList[[1]], 1]==="#",{}, {{"#P 0 0"}}];
blockList = Fold[If[StringTake[#2,1]==="#",Append[#1,{#2}],Insert[#1,#2,{{-1,-1}}]]&,blockList,stringList];
blockList = Flatten[cellBlockToPositions /@ blockList,1];
{xmin,ymin} =Min/@Transpose[blockList];
blockList = (#-{xmin-1,ymin-1}->1&)/@blockList;
final = ArrayPlot[Normal[SparseArray[blockList]]];
If[TrueQ[showDescriptions],final=Column[Prepend[descriptionList, final]]];
NotebookWrite[nb,ToBoxes[final]]
];
cellBlockToPositions[block_List]:=Module[
{xpos = ToExpression@StringCases[block[[1]],NumberString][[1]],
ypos= ToExpression@StringCases[block[[1]],NumberString][[2]]},
({ypos,xpos}+#)&/@Position[Characters /@ Rest[block], "*"]
];

Here it is in action...

ReadLifeFile[NotebookCreate[],"c:\\wri\\winlife\\patterns\\Gliders6.lif",True]

Let's build an importer
Part 2 — Write an options dialog (optional)

Row[{Checkbox[Dynamic[OptionValue[$FrontEnd, {ConversionOptions, "ImportOptions", "Life", "Show Description"}, True]]], "Include description"}]

pane = Deploy[Pane[Column[{%, Button["OK", NotebookClose[ButtonNotebook[]],ButtonExpandable->False]},ColumnAlignments->{Right}]]]

nb=NotebookSave[DialogPut[pane,"Life Import Options"],"c:\\temp\\ImportLife.nb"];

Let's build an importer
Part 3 — Plug it in

MathLink`CallFrontEnd[AddFileBrowserFilterPacket["ImportPictures",
{Item["Life Files", ReadLifeFile[#2, #1, OptionValue[$FrontEnd, {ConversionOptions, "ImportOptions", "Life", "Show Description"}]]&,
"lif", {"*.lif", "*.life"},OptionsNotebook->"c:\\temp\\ImportLife.nb",MenuEvaluator->Automatic]}]]

And too many little things to list

Including your suggestions!

Special thanks...

Lou D’Andria
P.J. Hinton
Andy Hunt

for ideas and code contributed to this talk